﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace HRM.HeThong
{
    public partial class frmDALConvert : Form
    {
        public frmDALConvert()
        {
            InitializeComponent();
        }


        private string regTenHam = @"(public|private|protect).*\s+([_a-zA-Z0-9]*)\s*\([^()]*\)\s*{";
        private string regProcedure = "SqlCommand[(]\".+";
        private string regThamSo = @"@.+[)]";
        private string regInfoClas = @"(public|partial|private|seadlead).+class.*\s+{(.*\s+)+}\s";
        private string regTenClass = @"(public|partial|private|seadlead).+class\s.+";
        //
        Dictionary<string, string> dicHam = new Dictionary<string, string>();
        StringBuilder sb = new StringBuilder();
        Regex regex = null;
        //
        private void btnConvert_Click(object sender, EventArgs e)
        {

            string sSource_I = txtSourceI.Text;
            string sSource_D = txtSourceD.Text;
            //
            string sDinhNghiaInterface = PhanTich_Interface(sSource_I);
            string sDinhNghiaHam = PhanTich_DinhNghiaHam(sSource_D);
            //
            txtChuyenDoi.Text = sDinhNghiaInterface + " " + sDinhNghiaHam;
        }


        private string PhanTich_DinhNghiaHam(string sSource)
        {
            string retVal = sSource;
            //1. Lấy danh sách định nghĩa các hàm

            //Lấy tên class
            regex = new Regex(regTenClass);
            Match matchTen = regex.Match(sSource);
            string sTenClass = "";
            if (matchTen.Success)
            {
                sTenClass = matchTen.Value.Split(new char[] { ':' })[1].Trim().Substring(1);
            }
            //

            regex = new Regex(regTenHam);
            MatchCollection matchCol = regex.Matches(sSource);
            //
            Match nextMatch = null;


            foreach (Match match in matchCol)
            {
                string sTenHam = match.Groups[0].Value;
                string sBodyHam = "";
                //
                nextMatch = match.NextMatch();
                if (nextMatch.Success)
                {
                    string sHamTiep = nextMatch.Groups[0].Value;
                    int idxCuoiHam = sSource.IndexOf(sHamTiep);
                    int idxDauHam = sSource.IndexOf(sTenHam);
                    sBodyHam = sSource.Substring(idxDauHam, idxCuoiHam - idxDauHam);
                }
                //
                sb.Append(sBodyHam);
                //
                if (!dicHam.Keys.Contains(sTenHam))
                    dicHam.Add(sTenHam, sBodyHam);
            }
            //txtSourceD.Text = sb.ToString();
            //
            if (dicHam.Count > 0)
                retVal = PhanTich_Ham(sTenClass);
            //
            return retVal;
        }


        private string PhanTich_Interface(string sSourceI)
        {
            string sContent = sSourceI;
            sContent = sContent + "THEM_DE_LOC_REG";

            //
            regex = new Regex(regInfoClas);
            Match match = regex.Match(sContent);
            if (match.Success)
            {
                //
                sContent = match.Value.Replace("[DataMember]", "");
            }
            //
            return sContent;
        }

        //chuyển từ nội dung wcf sang DAL
        private string PhanTich_Ham(string sTenClass)
        {
            sb = new StringBuilder();
            string sTenProcedure = "";
            List<string> lstThamSo = null;

            //Ghép phần header của class

            sb.AppendLine("public class " + sTenClass + "_Controller : Standard_Controller");
            sb.AppendLine("{");
            sb.AppendLine("    #region \"Contructor\"");
            sb.AppendLine("    private static " + sTenClass  + "_Controller _instance;");
            sb.AppendLine("    protected " + sTenClass  + "_Controller() { }");
            sb.AppendLine("    protected void Dispose()");
            sb.AppendLine("    {");
            sb.AppendLine("        _instance = null;");
            sb.AppendLine("    }");
            sb.AppendLine("    private static object _syncLock = new object();");
            sb.AppendLine("    public static " + sTenClass  + "_Controller Instance()");
            sb.AppendLine("    {");
            sb.AppendLine("        if (_instance == null)");
            sb.AppendLine("        {");
            sb.AppendLine("            lock (_syncLock)");
            sb.AppendLine("            {");
            sb.AppendLine("                if (_instance == null)");
            sb.AppendLine("                    _instance = new " + sTenClass  + "_Controller();");
            sb.AppendLine("            }");
            sb.AppendLine("         }");
            sb.AppendLine("         return _instance;");
            sb.AppendLine("    }");
            sb.AppendLine("    public static " + sTenClass  + "_Controller Instance(String transName)");
            sb.AppendLine("   {");
            sb.AppendLine("        if (!String.IsNullOrEmpty(transName))");
            sb.AppendLine("        {");
            sb.AppendLine("            " + sTenClass  + "_Controller _instanceTrans = new " + sTenClass + "_Controller();");
            sb.AppendLine("            _instanceTrans.Trans_Name = transName;");
            sb.AppendLine("            return _instanceTrans;");
            sb.AppendLine("        }");
            sb.AppendLine("         else");
            sb.AppendLine("            return Instance();");
            sb.AppendLine("    }");
            sb.AppendLine("    #endregion");
            sb.AppendLine("");
            sb.AppendLine("    public const String cs_Table_Name = \"\";");
            sb.AppendLine("");

            //-------------Ghép body các hàm

            foreach (string s in dicHam.Keys)
            {
                string sTenHam = s;
                string sBodyHam = dicHam[s];
                lstThamSo = new List<string>();

                //1.Append tên hàm giữ nguyên
                //sb.Append(sTenHam);

                //2.Phân tích body để lấy ra procedure, và tham số

                regex = new Regex(regProcedure);
                Match match = regex.Match(sBodyHam);
                if (match.Success)
                {
                    //Loại bỏ các ký tự thừa để lấy được tên Procedure
                    sTenProcedure = match.Value.Split(new char[]{','})[0].Replace("\"", "").Replace("(","").Replace(")","").Replace("SqlCommand", "");
                }
                //--Lấy các tham số
                regex = new Regex(regThamSo);
                MatchCollection matchCol = regex.Matches(sBodyHam);
                foreach (Match mThamSo in matchCol)
                {
                    string sTenThamSo = mThamSo.Value.Split(new char[] { ',' })[1].Replace(";", "").Replace(")","");
                    lstThamSo.Add(sTenThamSo);
                }

                //Ghép tên procedure và các biến
                sb.AppendLine(XuLy_GhepHam(sTenHam,sTenProcedure,lstThamSo));
            }
            
            //Hiển thị giá trị đã phân tích xong
            return sb.ToString();
        }


        //Ghép thành hàm theo DAL
       
        private string XuLy_GhepHam(string sTenHam, string sTenProcedure, List<string> lstThamSo)
        {
            StringBuilder sbTmp = new StringBuilder();
            sbTmp.Append(sTenHam);
            //
            //Tên hàm trả về 
            //  DataSet/DataTable: => execute DataSet
            //  xxxInfo: => trả về Object xxxInfo => Exceute Object
            //  int/bool/string/DateTime/object: => Execute Scalar
            // void :=> Execute Nonquery
            //
            bool includeChar = false;
            string sObjectTraVe = sTenHam.Split(new char[] { ' ' })[1];
            sbTmp.AppendLine("");
            //Execute DataSet
            if (sObjectTraVe.ToUpper().Contains("DataSet".ToUpper()))
            {
                sbTmp.Append("return DataConnect.ExecuteDataSet(DataConnect.WorkingConnect, Procedure_Name(cs_Table_Name, \"" + sTenProcedure + "\")");
            }
            else if (sObjectTraVe.ToUpper().Contains("DataTable".ToUpper()))
            {
                sbTmp.Append("return DataConnect.ExecuteDataTable(DataConnect.WorkingConnect, Procedure_Name(cs_Table_Name, \"" + sTenProcedure + "\")");
            }
            else if (sObjectTraVe.ToUpper().Contains("Info".ToUpper()))
            {
                string objName = sObjectTraVe;
                includeChar = true;
                sbTmp.Append("return CBO.FillObject<" + objName + ">(DataConnect.ExecuteRow(DataConnect.WorkingConnect, Procedure_Name(cs_Table_Name, \"" + sTenProcedure + "\")");
            }
            else if (sObjectTraVe.ToUpper().Contains("void".ToUpper()))
            {
                sbTmp.Append("return DataConnect.ExecuteNonQuery(DataConnect.WorkingConnect, Procedure_Name(cs_Table_Name, \"" + sTenProcedure + "\")");
            }

                
            else if ("object/int/bool/boolean/string/DateTime/Int64/Int32/Decimal/Float".ToUpper().Contains(sObjectTraVe.Trim().ToUpper()))
            {
                includeChar = true;
                sbTmp.Append("return Globals.Object_GetValue<" + sObjectTraVe.Trim() + ">(DataConnect.ExecuteScalar(DataConnect.WorkingConnect, Procedure_Name(cs_Table_Name, \"" + sTenProcedure + "\")");
            }

            //append tham số vào procedure
            foreach (string s in lstThamSo)
            {
                sbTmp.Append("," + s);
            }
            if (includeChar)
                sbTmp.Append(")");
            sbTmp.Append(");");

            //
            sbTmp.AppendLine("}");
            sbTmp.AppendLine("");
            sbTmp.AppendLine("}");
            //
            return sbTmp.ToString();
        }

    }
}
